
package com.platform.modules.event.service.Impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.platform.common.utils.DateUtils;
import com.platform.common.utils.JJRUtil;
import com.platform.common.utils.Query;
import com.platform.common.utils.RestResponse;
import com.platform.modules.event.dao.EventCalendarDao;
import com.platform.modules.event.entity.EventCalendarEntity;
import com.platform.modules.event.entity.MallReservationActivityEntity;
import com.platform.modules.event.service.EventCalendarBranchService;
import com.platform.modules.event.service.EventCalendarService;
import com.platform.modules.event.service.EventCategoryService;
;
import com.platform.modules.event.service.MallReservationActivityService;
import com.platform.modules.mall.entity.MallBranchEntity;
import com.platform.modules.mall.service.MallBranchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 模块表Service实现类
 *
 * @author
 * @date 2020-10-16 09:39:57
 */
@Service("eventCalendarService")
public class EventCalendarServiceImpl extends ServiceImpl<EventCalendarDao, EventCalendarEntity> implements EventCalendarService {

    @Autowired
    EventCategoryService eventCategoryService;

    @Autowired
    private EventCalendarBranchService eventCalendarBranchService;

    @Autowired
    private MallBranchService mallBranchService;

    @Autowired
    private MallReservationActivityService mallReservationActivityService;

    @Override
    public List<EventCalendarEntity> queryAll(Map<String, Object> params) {
        return baseMapper.queryAll(params);
    }

    @Override
    public Page queryPage(Map<String, Object> params) {
        //排序
        params.put("sidx", "T.sort");
        params.put("asc", false);
        Page<EventCalendarEntity> page = new Query<EventCalendarEntity>(params).getPage();
        return page.setRecords(baseMapper.selectEventCalendarPage(page, params));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(EventCalendarEntity eventCalendar) {
        eventCalendar.setCreateTime(new Date());

        this.save(eventCalendar);

        eventCategoryService.saveOrUpdate(eventCalendar.getId(), eventCalendar.getCategoryIds());
        //保存活动与支行关系
        eventCalendarBranchService.saveOrUpdate(eventCalendar.getId(), eventCalendar.getBranchIds());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(EventCalendarEntity eventCalendar) {

        this.updateById(eventCalendar);
        //保存活动与卡种关系
        eventCategoryService.saveOrUpdate(eventCalendar.getId(), eventCalendar.getCategoryIds());

        //保存活动与支行关系
        eventCalendarBranchService.saveOrUpdate(eventCalendar.getId(), eventCalendar.getBranchIds());
    }

    @Override
    public boolean delete(String id) {
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(String[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }


    @Override
    public List<EventCalendarEntity> eventCalendar(String year,String month,String categoryId,Set<String> keySet){
        StringBuffer sb =  new StringBuffer();
        sb.append(year).append("-").append(month.length()==1 ? "0" + month:month).append("-01");
        return baseMapper.eventCalendar(sb.toString(),categoryId,keySet);
    }

    @Override
    public List<EventCalendarEntity> eventCalendar2(String year, String month, String categoryId) {
        Map<String,Object> param =new HashMap<>();
        param.put("categoryId",categoryId);
        param.put("year",Integer.valueOf(year));
        param.put("month",Integer.valueOf(month));
        param.put("status",1);/*上架*/
//        param.put("hide",1);/*不隐藏*/
        List<EventCalendarEntity> entityList = baseMapper.eventCalendar2(param);

        Iterator<EventCalendarEntity> iterator = entityList.iterator();
        while(iterator.hasNext()){
            EventCalendarEntity next = iterator.next();

        }

        return entityList;
    }

    @Override
    public Map<String,Map<String,Object>> eventCalendarList(String year, String month, String categoryId, String branchId,List<EventCalendarEntity> activityList,String userId) throws IOException {
        Map<String, MallBranchEntity> branchMap = new HashMap<>();

        //获取节假日
        Map<Integer,String> holidayMap = JJRUtil.loop2(year,Integer.parseInt(month)+"");

        //获取传入年月的那一月天数，构建成map
        Map<String,Map<String,Object>> dayMap = getDayMap(Integer.parseInt(year),Integer.parseInt(month));

        //该月活动报名数据
        List<MallReservationActivityEntity> mallReservationActivityEntityList = mallReservationActivityService.list(new LambdaUpdateWrapper<MallReservationActivityEntity>()
                .likeRight(MallReservationActivityEntity::getActivityTime,year+"-"+month)
                .eq(MallReservationActivityEntity::getUserId,userId));

        dayMap.forEach((key,value)->{
            for(EventCalendarEntity activity : activityList){
                //活动数据判断处理
                activityJudge(key,dayMap,activity,year,month,holidayMap);
            }
            //支行详情数据处理
            branchJudge(key,dayMap,branchMap);

            //判断是否报名过
            activityRecordJudge(key,dayMap,year,month,mallReservationActivityEntityList);
        });

        return dayMap;
    }

    @Override
    public List<EventCalendarEntity> getActivityList(String date, String categoryId, String branchId) {

        //获取符合条件的活动列表
        return baseMapper.eventCalendarList(date,categoryId,branchId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBatch(List<EventCalendarEntity> normalList,Map<String, String> url) {
        Map<String, EventCalendarEntity> map = new HashMap<String, EventCalendarEntity>();
        for (EventCalendarEntity e : normalList
        ) {
            if (map.containsKey(e.getTitle())) {
                EventCalendarEntity ece = map.get(e.getTitle());
                List<String> list = ece.getCategoryIds();
                list.add(e.getCategoryId());
                ece.setCategoryIds(list);

            } else {
                map.put(e.getTitle(), e);
            }
        }

        for (EventCalendarEntity value : map.values()) {
//            Calendar calendar = new GregorianCalendar(1900, 0, -1);
//            int intDay = Integer.parseInt(value.getStartTime());
//            Date dd = DateUtils.addDays(calendar.getTime(), intDay);
//            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd");
//            value.setStartTime(simpleDateFormat.format(dd));
//            intDay = Integer.parseInt(value.getEndTime());
//            dd = DateUtils.addDays(calendar.getTime(), intDay);
//            value.setEndTime(simpleDateFormat.format(dd));
            value.setCreateTime(new Date());
            value.setCover(url.get(value.getRow().toString()));

            this.save(value);

            eventCategoryService.saveOrUpdate(value.getId(), value.getCategoryIds());

        }
    }

    private Map<String,Map<String,Object>> getDayMap(int year,int month){
        Calendar a = Calendar.getInstance();//获取当前时间
        a.set(Calendar.YEAR, year );
        a.set(Calendar.MONTH, month-1);// Calendar月份是以0开始的 所以要-1
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int day= a.get(Calendar.DATE);

        //排序
        class MyComparator implements Comparator<String>{
                        @Override
                        public int compare(String o1, String o2) {
                return Integer.parseInt(o1)-Integer.parseInt(o2);
            }
        }
        Map<String,Map<String,Object>> resultMap = new TreeMap<>(new MyComparator());
        Map<String,Object> map;
        for(int i = 1; i < day+1; i++){
            map = new HashMap<>();
            map.put("activity",new ArrayList<>());
            map.put("branch",new ArrayList<>());
            map.put("branchIds",new HashSet<>());
            resultMap.put(i+"",map);
        }
        return resultMap;
    }

    private void activityJudge(String key,Map<String,Map<String,Object>> dayMap,EventCalendarEntity activity,String year,String month,Map<Integer,String> holidayMap){

        int day = Integer.parseInt(key);
        //是否符合条件
        boolean isConform = false;
        //活动时间是否连续 1连续 2不连续
        int continuity = activity.getContinuity();


        //活动日期格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date startTime = new Date();
        Date endTime = new Date();
        Date activityTime = new Date();
        try {
            startTime = sdf.parse(activity.getStartTime());
            endTime = sdf.parse(activity.getEndTime());
        } catch (ParseException e) {
            RestResponse.error("活动日期格式化错误");
        }

        //连续
        if(continuity==1){
            try {
                activityTime = sdf.parse(year+"-"+month+"-"+(key.length()>1?key:("0"+key))+" 00:00:00");
            } catch (ParseException e) {
                RestResponse.error("活动日期格式化错误");
            }

            //是否在活动日期范围内
            if(startTime.getTime()<=activityTime.getTime()&&activityTime.getTime()<=endTime.getTime()){
                isConform = true;
            }

        //不连续
        }else{
            //日期规则
            int dateRule = activity.getDateRule();

            //获取活动结束时间年月日，判断是否为最后一月，避免不满一个月有些条件不在活动时间范围内
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endTime);
            int endYear = calendar.get(Calendar.YEAR);
            int endMonth = calendar.get(Calendar.MONTH)+1;
            int endDay = calendar.get(Calendar.DATE);
            calendar.setTime(startTime);
            int startYear = calendar.get(Calendar.YEAR);
            int startMonth = calendar.get(Calendar.MONTH)+1;
            int startDay = calendar.get(Calendar.DATE);
            //获取周几，1为周一，7为周日
            calendar.set(Calendar.YEAR,Integer.parseInt(year));
            calendar.set(Calendar.MONTH,Integer.parseInt(month)-1);
            calendar.set(Calendar.DATE,day);
            int week = calendar.get(Calendar.DAY_OF_WEEK);
            week = week == 1 ? 7 : (week-1);


            //判断是否为活动第一个月
            boolean isFirstMonth = Integer.parseInt(year)==startYear&&Integer.parseInt(month)==startMonth;
            //判断该日是否在第一个月的活动有效期内
            boolean isFirstValidity = isFirstMonth && startDay <= day;

            //判断是否为活动最后一个月
            boolean isLastMonth = Integer.parseInt(year)==endYear&&Integer.parseInt(month)==endMonth;
            //判断该日是否在最后一个月的活动有效期内
            boolean isLastValidity = isLastMonth && endDay >= day;



            //每月十号
            if(dateRule==0){
                if(day==10){
                    if(isFirstMonth){
                        isConform = isFirstValidity;
                    }else if(isLastMonth){
                        isConform = isLastValidity;
                    }else{
                        isConform = true;
                    }
                }

            //每月九号、十九号、二十九号
            }else if(dateRule==1){
                if(day==9||day==19||day==29){
                    if(isFirstMonth){
                        isConform = isFirstValidity;
                    }else if(isLastMonth){
                        isConform = isLastValidity;
                    }else{
                        isConform = true;
                    }
                }

            //每周六、周日
            }else if(dateRule==2){
                if(week==6||week==7){
                    if(isFirstMonth){
                        isConform = isFirstValidity;
                    }else if(isLastMonth){
                        isConform = isLastValidity;
                    }else{
                        isConform = true;
                    }
                }

            //每周五至周日、法定节假日
            }else{
                if(week==5||week==6||week==7||holidayMap.containsKey(day)){
                    if(isFirstMonth){
                        isConform = isFirstValidity;
                    }else if(isLastMonth){
                        isConform = isLastValidity;
                    }else{
                        isConform = true;
                    }
                }
            }
        }

        //符合条件
        if(isConform){
            ((List)dayMap.get(key).get("activity")).add(activity);
            String[] branchIdArr = activity.getBranchId().split(",");
            for(String branchId : branchIdArr){
                ((Set)dayMap.get(key).get("branchIds")).add(branchId);
            }
        }


    }

    private void branchJudge(String key,Map<String,Map<String,Object>> dayMap,Map<String,MallBranchEntity> branchMap){
        Set<String> branchIdSet = ((Set)dayMap.get(key).get("branchIds"));
        MallBranchEntity branchEntity;
        for (String branchId:branchIdSet) {
            //支行map中有该支行数据，直接通过id获取
            if(branchMap.containsKey(branchId)){
                branchEntity = copyBranch(branchMap.get(branchId));
                ((List)dayMap.get(key).get("branch")).add(branchEntity);
            }else{
                //支行map中没有该支行数据，通过id查询数据库，并把该次查询结果添加到支行map 避免重复查询数据库
                branchEntity = mallBranchService.getById(branchId);
                ((List)dayMap.get(key).get("branch")).add(branchEntity);
                branchMap.put(branchId,branchEntity);
            }


        }
    }

    private void activityRecordJudge(String key,Map<String,Map<String,Object>> dayMap,String year, String month,List<MallReservationActivityEntity> reservationActivityEntityList){
        String day = key.length()>1?key:"0"+key;
        String date = year+"-"+month+"-"+day;
        String activityTime = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        //支行列表
        List<MallBranchEntity> branchList = ((List)dayMap.get(key).get("branch"));
        //活动列表
        List<EventCalendarEntity> activityList = ((List)dayMap.get(key).get("activity"));
        for(EventCalendarEntity activity : activityList){
            for(MallBranchEntity branch : branchList){
                for(MallReservationActivityEntity activityRecord : reservationActivityEntityList){
                    activityTime = sdf.format(activityRecord.getActivityTime());
                    //判断活动id 支行id 日期是否相同
                    if(activity.getId().equals(activityRecord.getActivityId())&&branch.getId().equals(activityRecord.getBranchId())&&date.equals(activityTime)){
                        branch.setReported(true);
                        break;
                    }
                }
            }
        }
    }

    //生成一个新的支行对象
    private MallBranchEntity copyBranch(MallBranchEntity oldBranch){
        MallBranchEntity newBranch = new MallBranchEntity();
        newBranch.setId(oldBranch.getId());
        newBranch.setName(oldBranch.getName());
        newBranch.setDetails(oldBranch.getDetails());
        newBranch.setWorkTime(oldBranch.getWorkTime());
        newBranch.setImgUrl(oldBranch.getImgUrl());
        return newBranch;
    }

}
